using UnityEngine;
using JufGame.CptMod;
using JufGame.MathHelper;
using System;

namespace JufGame
{
	public class LOD_Character : MonoBehaviour, IComparable<LOD_Character>
	{
		//影响不同重要性的5种因子
		public Observability Observability => observability;
		public Attention Attention => attention;
		public PlayerMemory Memory => memory;
		public ReturnTime ReturnTime => returnTime;
		public Duration Duration => duration;
		//当前角色使用的特征解决方案
		public FeatureSolution Feature_Solution => featureSolution;
		public float ValueHeuristic{ get; private set; }
		[SerializeField] private Observability observability;
		[SerializeField] private Attention attention;
		[SerializeField] private PlayerMemory memory;
		[SerializeField] private ReturnTime returnTime;
		[SerializeField] private Duration duration;
		[SerializeField] private FeatureSolution featureSolution;
		[SerializeField] private FeatureGraph featureGraph;
        [SerializeField] private Vector3 criticalityVector;
		private void Awake()
		{
			attention = new Attention(observability.Renderer.transform);
			memory = new PlayerMemory();
			returnTime = new ReturnTime();
			duration = new Duration();
			criticalityVector = Vector3.zero;
		}
		private void OnEnable()
		{
			featureSolution = featureGraph.CompleteSolutions[featureGraph.DefaultSolutionID];
		}
		/// <summary>
		/// 清空重要程度向量，以便重新计算
		/// </summary>
		public void ResetCriticalityVec()
		{
			criticalityVector = Vector3.zero;
		}
		/// <summary>
		/// 计算重要程度向量，调用前确保各个因子都已计算
		/// </summary>
		public void CalcCriticalityVec()
		{
			//ShowFactors();
			//穿帮状态(Unrealistic State)
			criticalityVector.x += observability.ObserValue * attention.RealAttention;
			//基本不连续(Fundamental Discontinuity)
			criticalityVector.y += memory.MemoryValue * returnTime.RTValue;
			//长期穿帮行为(Unrealistic Long-Term Behavior)
			criticalityVector.z += attention.RealAttention * memory.MemoryValue * duration.DurtVaule * 10;
		}
		/// <summary>
		/// 计算启发值，结果存储在ValueHeuristic
		/// </summary>
		public void CalcValueHeuristic(TransType transType)
		{
			var isUpgrade = transType == TransType.Upgrade;
			var W_Matrix = featureSolution.GetWMatrix(transType);
			ValueHeuristic = Matrix.Multiply_GetMaxMin(ref criticalityVector, W_Matrix, isUpgrade);
		}
		/// <summary>
		/// 扩展角色，选出最高价值的转换
		/// </summary>
		/// <param name="nomalized_M">归一化的资源因子向量</param>
		/// <param name="transType">转换类型</param>
		public SolutionTrans ExpandCharacter(TransType transType, Vector4 resourceMul, ref float bestRatio)
		{
			float tpRatio;
			SolutionTrans bestTrans = null;
			bestRatio = transType == TransType.Upgrade ? float.MinValue : float.MaxValue; 
			var allTrans = Feature_Solution.GetTransitions(transType);
			for(int i = 0; i < allTrans.Count; ++i)
			{
				tpRatio = Vector3.Dot(criticalityVector, allTrans[i].RelAudacity) / Vector4.Dot(resourceMul, allTrans[i].RelCost);
				if(LOD_Trader.IsBetterRatio(tpRatio, bestRatio, transType))
				{
					bestRatio = tpRatio;
					bestTrans = allTrans[i];
				}
			}
			return new SolutionTrans(this, bestTrans);
		}
		/// <summary>
		/// 执行交易
		/// </summary>
		public void Real_RunTrade(FeatureSolution solution)
		{
			featureSolution = solution;
		}
        public int CompareTo(LOD_Character other)
        {
			return ValueHeuristic.CompareTo(other.ValueHeuristic);
        }

		#if UNITY_EDITOR
		public void UI_GetCurrentSaturation()
		{
			observability.ResetSaturationSize(Camera.main);
		}
		private void ShowFactors()
		{
			Debug.Log("ob: "+ observability.ObserValue);
			Debug.Log("at: "+ attention.RealAttention);
			Debug.Log("me: "+ memory.MemoryValue);
			Debug.Log("rt: "+ returnTime.RTValue);
			Debug.Log("du: "+ duration.DurtVaule);
		}
		#endif
	}
}
